package com.youan.pangu.security.configuration;

import com.youan.pangu.base.bean.SystemParameter;
import com.youan.pangu.security.brower.filter.ValidateCodeFilter;
import com.youan.pangu.security.brower.handler.PanguFailureAuthenticationHandler;
import com.youan.pangu.security.brower.handler.PanguSuccessAuthenticationHandler;
import com.youan.pangu.security.listener.SecurityCheckAppStartedListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @description:
 * @author: 辛晟昊
 * @time: 2020/3/8 19:24
 */
@Configuration
public class BaseSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Autowired
    private ValidateCodeFilter validateCodeFilter;
    @Autowired
    private SystemParameter systemParameter;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/**/*.js", "/lang/*.json", "/**/*.css", "/**/*.js", "/**/*.map", "/**/*.html",
                "/**/*.png", "/**/swagger-resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        validateCodeFilter.setAuthenticationFailureHandler(authenticationFailureHandler);

        FormLoginConfigurer<HttpSecurity> configurer =
        http
                .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
                .formLogin()
                    //.loginPage("/authentication/requireLogin")
                    .loginProcessingUrl("/authentication/form")
                    .failureHandler(authenticationFailureHandler)
                    .successHandler(authenticationSuccessHandler);
        if(systemParameter.getMode().equals("deve")){
            configurer.and().authorizeRequests().antMatchers().permitAll();
        }else{
            configurer.and()
                    .authorizeRequests()
                    .antMatchers("/authentication/requireLogin", "/code/*").permitAll()
                    .antMatchers(getSwaggerMatchers()).permitAll()
                    .anyRequest().authenticated();
        }

        configurer.and().csrf().disable();;
    }

    private String[] getSwaggerMatchers() {
        return new String[]{
                "/swagger-ui.html",
                "/swagger-resources/**",
                "/images/**",
                "/webjars/**",
                "/v2/api-docs",
                "/configuration/ui",
                "/configuration/security"
        };
    }

    @Bean
    public AuthenticationSuccessHandler successAuthenticationHandler(){
        return new PanguSuccessAuthenticationHandler();
    }

    @Bean
    public AuthenticationFailureHandler failureAuthenticationHandler(){
        return new PanguFailureAuthenticationHandler();
    }

    /**
     * 检查Security运行中必须的组件是否设置
     * @return
     */
    @Bean
    public SecurityCheckAppStartedListener securityCheckListener(){
        return new SecurityCheckAppStartedListener();
    }

}
